

#include <CGAL/Linear_cell_complex.h>
#include <CGAL/Linear_cell_complex_constructors.h>
#include <CGAL/Linear_cell_complex_operations.h>
#include <CGAL/IO/Polyhedron_iostream.h>
#include <CGAL/IO/File_header_OFF.h>
#include <CGAL/IO/File_scanner_OFF.h>
#include <CGAL/Cartesian.h>
#include <iostream>
#include <fstream>


#include "linear_cell_complex_3_viewer_qt.h"
#include "boost/program_options.hpp"
#include "region_growing.h"


struct ColoredFacetLCCItem
{
	template<class Refs>
	struct Dart_wrapper
	{
		typedef CGAL::Dart<2, Refs> Dart;
		typedef CGAL::Cell_attribute_with_point<Refs, void, CGAL::Tag_true> Vertex_attribute;
		typedef CGAL::Cell_attribute<Refs, int, CGAL::Tag_true> Facet_attribute;
		typedef CGAL::cpp11::tuple<Vertex_attribute, void, Facet_attribute> Attributes;
	};
};

typedef CGAL::Cartesian<double>                     Kernel;
typedef CGAL::Linear_cell_complex_traits<3, Kernel> Traits;
typedef CGAL::Linear_cell_complex<2, 3, Traits, ColoredFacetLCCItem>     LCC_3;

namespace boostPO = boost::program_options;

int main(int argc, char** argv)
{
	/* ARG PARSER *****************************************************/
	std::string fn_input;
	int nbSeed;
	
	boostPO::variables_map vm;
	boostPO::options_description desc("Allowed options");
	desc.add_options()
		("help,h",
			"produce help message")
		("input,i",
			boostPO::value(&fn_input)->required(),
			"mesh's filanme to load (supported format : .off)")
		("viewer,v",
			"Enable 3D mesh viewer")
		("nb-seed,s",
			boostPO::value(&nbSeed)->default_value(3),
			"Number of seed")
		;
		
	boostPO::positional_options_description p;
	p.add("input", -1);
	
	try
	{	
		boostPO::store(
			boostPO::command_line_parser(argc, argv).
				options(desc).positional(p).run(), vm);
		boostPO::notify(vm);
	}
	catch(boost::program_options::error& e)
	{
		std::cerr << e.what() << "\n";
		std::cout << desc << "\n";
		exit(EXIT_FAILURE);
	}
	
	if(vm.count("help") || fn_input.size() == 0)
	{
		std::cout << desc << "\n";
		exit(EXIT_SUCCESS);
	}
	
	/* ARG PARSER *****************************************************/

	std::ifstream meshFile(fn_input.c_str());
	if(meshFile.fail())
	{
		std::cerr << "File not found : " << fn_input << std::endl;
		return EXIT_FAILURE;
	}

	LCC_3 lcc;

	//Load mesh file
	CGAL::load_off(lcc, meshFile);

	//Display some informations
	std::cout << "Number of vertices : " << lcc.one_dart_per_cell<0>().size() << std::endl;
	std::cout << "Number of edges : " << lcc.one_dart_per_cell<1>().size() << std::endl;
	std::cout << "Number of faces : " << lcc.one_dart_per_cell<2>().size() << std::endl;

	RegionGrowing<LCC_3> regionGrowing(lcc, nbSeed);
	regionGrowing.growingStep1();
	regionGrowing.growingStep2();
	regionGrowing.growingStep3();

	//Viewer
	if(vm.count("viewer")) 
	{
		display_region_growing(regionGrowing);
	}

	return EXIT_SUCCESS;
}

